package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.execption.RestErrorResponse;
import com.xuecheng.base.execption.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Author dingchunlin
 * @Date 2024/3/29 20:58
 * @Version 1.0.0
 */
@Service
@Slf4j
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    /**
     * 查询课程计划树型结构
     * @param courseId
     * @return
     */
    @Override
    public List<TeachplanDto> getTreeNodes(Long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    /**
     * 添加或修改课程计划
     * @param teachplanDto
     */
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        //课程计划id
        Long id = teachplanDto.getId();
        //修改课程计划
        if(id!=null){
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }else{
            //取出同父同级别的课程计划数量
            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            //设置排序号
            teachplanNew.setOrderby(count+1);
            BeanUtils.copyProperties(teachplanDto,teachplanNew);
            teachplanMapper.insert(teachplanNew);
        }

    }

    /**
     * 删除课程计划
     * @param planId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deletePlanById(Long planId) {
        //首先查询是否有下级目录
        LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Teachplan::getParentid,planId);
        Integer count = teachplanMapper.selectCount(lambdaQueryWrapper);
        if (count > 0){
            throw new XueChengPlusException("课程计划信息还有子级信息，无法操作");
        }
        //没有则可以正常删除
        teachplanMapper.deleteById(planId);
        //将关联的信息进行删除
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,planId));
    }

    /**
     * 课程计划向下移动
     * @param planId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void movedown(Long planId) {
        //首先查询出具体的数据
        Teachplan beforeTeachplan = teachplanMapper.selectById(planId);
        //获取最大的层数
        int num = getTeachplanCount(beforeTeachplan.getCourseId(), beforeTeachplan.getParentid());
        //原来的排序数
        Integer before = beforeTeachplan.getOrderby();
        //如果当前就是最后一级就不让移动
        if (beforeTeachplan.getOrderby().equals(num)){
            throw new XueChengPlusException("已经是最下一级不能移动");
        }
        //将其下一级进行查询
        LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Teachplan::getParentid,beforeTeachplan.getParentid());
        lambdaQueryWrapper.eq(Teachplan::getCourseId,beforeTeachplan.getCourseId());
        lambdaQueryWrapper.eq(Teachplan::getOrderby,before+1);
        Teachplan afterTeacherPlan = teachplanMapper.selectOne(lambdaQueryWrapper);
        //获取下一级的排序顺序
        Integer after = afterTeacherPlan.getOrderby();
        //将排序的顺序进行修改
        beforeTeachplan.setOrderby(after);
        afterTeacherPlan.setOrderby(before);
        //执行修改
        teachplanMapper.updateById(beforeTeachplan);
        teachplanMapper.updateById(afterTeacherPlan);
    }

    /**
     * 课程计划向上移动
     *
     * @param planId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void moveup(Long planId) {
        //首先查询出具体的数据
        Teachplan beforeTeachplan = teachplanMapper.selectById(planId);
        //如果当前就是第一级就不让移动
        if (beforeTeachplan.getOrderby().equals(1)){
            throw new XueChengPlusException("已经是最上一级不能移动");
        }
        //原来的排序数
        Integer before = beforeTeachplan.getOrderby();
        //将其下一级进行查询
        LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Teachplan::getParentid,beforeTeachplan.getParentid());
        lambdaQueryWrapper.eq(Teachplan::getCourseId,beforeTeachplan.getCourseId());
        lambdaQueryWrapper.eq(Teachplan::getOrderby,before - 1);
        Teachplan afterTeacherPlan = teachplanMapper.selectOne(lambdaQueryWrapper);
        //获取下一级的排序顺序
        Integer after = afterTeacherPlan.getOrderby();
        //将排序的顺序进行修改
        beforeTeachplan.setOrderby(after);
        afterTeacherPlan.setOrderby(before);
        //执行修改
        teachplanMapper.updateById(beforeTeachplan);
        teachplanMapper.updateById(afterTeacherPlan);
    }

    /**
     * 课程计划和媒资信息绑定
     *
     * @param bindTeachplanMediaDto
     */
    @Override
    public TeachplanMedia  associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan==null){
            XueChengPlusException.cast("教学计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if(grade!=2){
            XueChengPlusException.cast("只允许第二级教学计划绑定媒资文件");
        }
        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,teachplanId));

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;

    }

    /**
     * 课程计划和媒资解除绑定
     *
     * @param teachPlanId
     * @param mediaId
     */
    @Override
    public void associationMedia(Long teachPlanId, String mediaId) {
        Teachplan teachplan = teachplanMapper.selectById(teachPlanId);
        if(teachplan==null){
            XueChengPlusException.cast("教学计划不存在");
        }
        //创建删除条件
        LambdaQueryWrapper<TeachplanMedia> teachplanMediaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        teachplanMediaLambdaQueryWrapper.eq(TeachplanMedia::getTeachplanId,teachPlanId);
        teachplanMediaLambdaQueryWrapper.eq(TeachplanMedia::getMediaId,mediaId);
        //执行删除
        teachplanMediaMapper.delete(teachplanMediaLambdaQueryWrapper);
    }

    /**
     * 根据课程id获取教师
     *
     * @param courseId
     * @return
     */
    @Override
    public List<TeachplanDto> findTeachplanTree(Long courseId) {
        return null;
    }


    /**
     * 获取最新的排序号
     * @param courseId
     * @param parentId
     * @return
     */
    private int getTeachplanCount(long courseId,long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentId);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return count;
    }



}
